package org.lib093.update

import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import dalvik.system.PathClassLoader
import native.BspatchUtil
import org.lib093.update.databinding.ActivityMainBinding
import java.io.*

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

    }

    fun testDiff() {
        val file = copy4Assets()
        val classLoader = PathClassLoader(file.absolutePath, classLoader)
        try {
            val test = classLoader.loadClass("Test")
            val main = test.getDeclaredMethod("test")
            main.invoke(null)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun copy4Assets(): File {
        val externalFilesDir = getExternalFilesDir("")
        val dexFile = File(externalFilesDir, "new.dex")
        if (!dexFile.exists()) {
            var `is`: BufferedInputStream? = null
            var os: BufferedOutputStream? = null
            try {
                `is` = BufferedInputStream(assets.open("new2.dex"))
                os = BufferedOutputStream(FileOutputStream(dexFile))
                val buffer = ByteArray(4096)
                var len: Int
                while (`is`.read(buffer).also { len = it } != -1) {
                    os.write(buffer, 0, len)
                }
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                try {
                    `is`!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                try {
                    os!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        return dexFile
    }

    fun patch(view: View?) {
        val newFile = File(getExternalFilesDir("apk"), "app.apk")
        val patchFile = File(getExternalFilesDir("apk"), "patch.apk")
        if (!patchFile.exists()){
            //sdcard/Android/data/org.lib093.update/files/apk
            Toast.makeText(this, "差分包不存在请先生成差分包", Toast.LENGTH_SHORT).show()
            return
        }
        val result: Int = BspatchUtil.patch(
            applicationInfo.sourceDir, newFile.absolutePath,
            patchFile.absolutePath
        )
        if (result == 0) {
            Toast.makeText(this, "安装新产生的app.apk", Toast.LENGTH_SHORT).show()
            install(newFile)
        }else{
            Toast.makeText(this, "合成失败", Toast.LENGTH_SHORT).show()
        }
    }
    fun diff(view: View?){
        val v2 = File(getExternalFilesDir("apk"), "2.apk")
        if (!v2.exists()){
            //sdcard/Android/data/org.lib093.update/files/apk
            Toast.makeText(this, "请将新版apk 放入apk文件夹下", Toast.LENGTH_SHORT).show()
            return
        }
        val patchFile = File(getExternalFilesDir("apk"), "patch.apk")
        val result: Int = BspatchUtil.diff(
            applicationInfo.sourceDir, v2.absolutePath,
            patchFile.absolutePath
        )
        if (result == 0) {
            Toast.makeText(this, "差分包创建成功", Toast.LENGTH_SHORT).show()
        }else{
            Toast.makeText(this, "差分包创建失败", Toast.LENGTH_SHORT).show()
        }
    }

    private fun install(file: File) {
        val intent = Intent(Intent.ACTION_VIEW)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
            val apkUri = FileProvider.getUriForFile(this, "$packageName.fileprovider", file)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
        }
        startActivity(intent)
    }
}